package com.cuitrip.app.init;

import android.content.Context;
import android.os.Environment;
import android.os.Handler;

import com.alipay.euler.andfix.patch.PatchManager;
import com.cuitrip.apiservice.BusinessHelper;
import com.cuitrip.app.MainApplication;
import com.cuitrip.business.webview.H5UrlMaker;
import com.lab.logtrack.AppLog;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by ak on 15/12/23.
 */
public class AppInitManager {

    private static final String TAG = "euler";

    private InitializerListener mListener;

    public void setInitializerListener(InitializerListener mListener) {
        this.mListener = mListener;
    }

    public void removeInitializerListener() {
        this.mListener = null;
    }

    private static String apatchPath;
    private static final String APATCH_PATH_DIR = "/cuitrip";
    private static final String DOWNLOAD_HOST = BusinessHelper.API_URL + H5UrlMaker.BUG_FIX_URL;

    private static final String PATCH_SUFFIX = "_out.apatch";

    private String downloadUrl;

    /**
     * patch manager
     */
    private PatchManager mPatchManager;

    private static AppInitManager appInitManager;

    public enum InitProgress {NULL, RUN, FINISHED}

    private InitProgress mProgress = InitProgress.NULL;

    private Handler mHandler = new Handler();

    public static AppInitManager getInstance() {
        if (appInitManager == null) {
            appInitManager = new AppInitManager();
        }
        return appInitManager;
    }

    private AppInitManager() {
        downloadUrl = DOWNLOAD_HOST + "/" + MainApplication.getInstance().getVersionName() + PATCH_SUFFIX;
        apatchPath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + APATCH_PATH_DIR + "/" + MainApplication.getInstance().getVersionName() + PATCH_SUFFIX;
        File patchDir = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + APATCH_PATH_DIR);
        if (!patchDir.exists()) {
            patchDir.mkdir();
        }
    }

    public void initBugFix(Context context) {
        mProgress = InitProgress.RUN;
        downloadAsyn(context, downloadUrl, apatchPath);
        AppLog.d(TAG, "apatch:" + downloadUrl + " not exist.");
    }


    public void addPatch(Context context) {
        try {
            if (!new File(apatchPath).exists()) {
                return;
            }
            // initialize
            mPatchManager = new PatchManager(context);
            mPatchManager.init(MainApplication.getInstance().getVersionName());
            AppLog.d(TAG, "inited.");

            // load patch
            mPatchManager.loadPatch();
            AppLog.d(TAG, "apatch loaded.");

            // add patch at runtime
            mPatchManager.addPatch(apatchPath);
            AppLog.d(TAG, "apatch added.");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (UnsatisfiedLinkError e) {
            e.printStackTrace();
        }
    }

    private void onFinish() {
        mProgress = InitProgress.FINISHED;
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mListener != null) {
                    mListener.onFinished();
                }
            }
        });
    }

    /**
     * 是否已经执行完成
     *
     * @return
     */
    public boolean isReadyToGo() {
        return mProgress != InitProgress.RUN;
    }


    private void downloadAsyn(final Context context, final String url, final String fileName) {
        AppLog.d("download patch");
        OkHttpClient mOkHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .build();
        final Call call = mOkHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                onFinish();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                File file = new File(fileName);
                if (file.exists()) {
                    file.delete();
                }
                InputStream is = null;
                byte[] buf = new byte[1024];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    is = response.body().byteStream();

                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    fos.flush();
                    //如果下载文件成功，第一个参数为文件的绝对路径
                    onFinish();
                } catch (IOException e) {

                } finally {
                    try {
                        if (is != null) is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null) fos.close();
                    } catch (IOException e) {
                    }
                }
            }

        });
    }


}
